/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ui;

import control.MStockMidlet;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import listener.ICommandListener;
import listener.IKeyListener;

/**
 *
 * @author kien.tran
 */
public class List extends ACanvas {

    private ListItemCollections items = new ListItemCollections();
    private int selectedIndex = 0;
    private int itemY = 0;

    public List() {
    }

    public List(Display display, MStockMidlet control, String title, Image background, Image icon) {
        super(display, control, title, background, icon);
        itemY = getItemY();
    }

    public void paintItems(Graphics g) {
        selectedItem();
        itemsAreaProcess();
        int x = getItemX(), y = itemY;
        AListItem item = null;
        if (items != null && items.size() > 0) {
            for (int i = firstIndex; i <= lastIndex; i++) {
                item = (AListItem) items.elementAt(i);
                item.paint(x, y, g);
                y += item.getHeight();
            }
        }
    }

    public void addItem(AListItem item) {
        items.addElement(item, this);
    }

    public void removeItem(AListItem item) {
        items.removeElement(item);
    }

    public int getItemsSize() {
        return items.size();
    }

    public int getSelectedIndex() {
        return selectedIndex;
    }

    public AListItem getSelectedItem() {
        return items.elementAt(selectedIndex);
    }

    public ListItemCollections getSelectedItems() {
        AListItem item = null;
        ListItemCollections list = null;
        for (int i = 0; i < items.size(); i++) {
            item = items.elementAt(i);
            if (item instanceof CheckItem) {
                CheckItem check = (CheckItem) item;
                if (check.isChecked()) {
                    if (list == null) {
                        list = new ListItemCollections();
                    }
                    list.addElement(item, this);
                }
            } else if (item instanceof RadioItem) {
                RadioItem radio = (RadioItem) item;
                if (radio.isChecked()) {
                    if (list == null) {
                        list = new ListItemCollections();
                    }
                    list.addElement(item, this);
                }
            }
        }
        return list;
    }

    private void selectedItem() {
        int itemsSize = items.size();
        if (itemsSize == 0) {
            return;
        }
        int i = 0;
        AListItem item = null;
        newIndex += itemsSize;
        newIndex = newIndex % itemsSize;
        if (selectedIndex != newIndex) {
            selectedIndex = newIndex;
        }

        item = items.elementAt(selectedIndex);
        if (item instanceof StringItem) {
            boolean isHas = false;
            for (i = selectedIndex + 1; i < itemsSize; i++) {
                item = items.elementAt(i);
                if (!(item instanceof StringItem)) {
                    selectedIndex = i;
                    newIndex = i;
                    isHas = true;
                    break;
                }
            }
            if (!isHas) {
                for (i = 0; i < selectedIndex; i++) {
                    item = items.elementAt(i);
                    if (!(item instanceof StringItem)) {
                        selectedIndex = i;
                        newIndex = i;
                        break;
                    }
                }
            }
        }

        item = items.elementAt(oldIndex);
        item.setFocus(false);

        item = items.elementAt(selectedIndex);
        item.setFocus(true);
    }

    private void itemsAreaProcess() {
        int itemsSize = items.size();

        if (itemsSize == 0) {
            firstIndex = -1;
            lastIndex = -1;
            return;
        }

        int i, x = getItemX(), y = getItemY();
        AListItem item;
        switch (moveAction) {
            case MOVE_NONE:
                // start dawing at first item
                firstIndex = 0;
                oldIndex = 0;
                newIndex = 0;
                selectedItem();
                lastIndex = itemsSize - 1;
                // draw selected
                item = (AListItem) items.elementAt(selectedIndex);
                y = getItemY() + item.getHeight();
                // finding lastIndex
                for (i = selectedIndex + 1; i < itemsSize; i++) {
                    item = (AListItem) items.elementAt(i);
                    y += item.getHeight();
                    if (!item.isPaint(x, y)) {
                        lastIndex = i;
                        break;
                    }
                }
                break;

            default:
                // draw first to selected - 1
                itemY = getItemY();
                y = getItemY();
                if (firstIndex >= selectedIndex) {
                    // start dawing at first item
                    firstIndex = selectedIndex;
                    lastIndex = itemsSize - 1;
                    // draw selected
                    item = (AListItem) items.elementAt(selectedIndex);
                    y = getItemY() + item.getHeight();
                    // finding lastIndex
                    for (i = selectedIndex + 1; i < itemsSize; i++) {
                        item = (AListItem) items.elementAt(i);
                        y += item.getHeight();
                        if (!item.isPaint(x, y)) {
                            lastIndex = i;
                            break;
                        }
                    }
                    if (lastIndex == itemsSize - 1 && y < getHeight() - getFooterHeight()) {
                        itemY = getHeight() - getFooterHeight() - getStyle().getBodyStyle().getPadding().getBottom();
                        for (i = lastIndex; i >= 0; i--) {
                            item = (AListItem) items.elementAt(i);
                            itemY -= item.getHeight();
                            if (!item.isPaint(x, itemY)) {
                                firstIndex = i;
                                break;
                            }
                        }
                        itemY = getItemY();
                    }
                } else if (lastIndex <= selectedIndex) {
                    // draw selected
                    item = (AListItem) items.elementAt(selectedIndex);
                    lastIndex = selectedIndex;
                    itemY = getHeight() - (getFooterHeight() + item.getHeight() + getStyle().getBodyStyle().getPadding().getBottom());
                    for (i = selectedIndex - 1; i >= 0; i--) {
                        item = (AListItem) items.elementAt(i);
                        itemY -= item.getHeight();
                        if (!item.isPaint(x, itemY)) {
                            firstIndex = i;
                            break;
                        }
                    }
                    if (firstIndex == 0 && itemY > getItemY()) {
                        int more = itemY - getItemY();
                        for (i = selectedIndex + 1; i < itemsSize; i++) {
                            item = (AListItem) items.elementAt(i);
                            more -= item.getHeight();
                            if (more <= 0) {
                                lastIndex = i;
                                break;
                            }
                        }
                        itemY = getItemY();
                    }
                } else {
                    if (moveAction == MOVE_DOWN) {
                        for (i = firstIndex; i < selectedIndex; i++) {
                            item = (AListItem) items.elementAt(i);
                            y += item.getHeight();
                        }
                        // draw selected
                        item = (AListItem) items.elementAt(selectedIndex);
                        // draw selected + 1 to last
                        if (!item.isSelectedPaint(x, y)) {
                            lastIndex = selectedIndex;
                            itemY = getHeight() - getFooterHeight() - item.getHeight() - getStyle().getBodyStyle().getPadding().getBottom();
                            for (i = selectedIndex - 1; i >= 0; i--) {
                                item = (AListItem) items.elementAt(i);
                                itemY -= item.getHeight();
                                if (!item.isPaint(x, itemY)) {
                                    firstIndex = i;
                                    break;
                                }
                            }
                        } else {
                            y = getItemY();
                            for (i = firstIndex; i <= lastIndex; i++) {
                                item = (AListItem) items.elementAt(i);
                                y += item.getHeight();
                            }
                            if (y < getHeight() - getFooterHeight() - getStyle().getBodyStyle().getPadding().getBottom()) {
                                for (i = lastIndex + 1; i < itemsSize; i++) {
                                    item = (AListItem) items.elementAt(i);
                                    y += item.getHeight();
                                    if (!item.isPaint(x, y)) {
                                        itemY = getItemY();
                                        lastIndex = i;
                                        break;
                                    }
                                }
                            }
                        }
                    } else if (moveAction == MOVE_UP) {
                        y = getHeight() - getFooterHeight() - getStyle().getBodyStyle().getPadding().getBottom();
                        for (i = lastIndex; i > selectedIndex; i--) {
                            item = (AListItem) items.elementAt(i);
                            y -= item.getHeight();
                        }
                        // draw selected
                        item = (AListItem) items.elementAt(selectedIndex);
                        y -= item.getHeight();
                        // draw selected + 1 to last
                        if (!item.isSelectedPaint(x, y)) {
                            firstIndex = selectedIndex;
                            itemY = getItemY();
                            y = getItemY();
                            for (i = selectedIndex; i < itemsSize; i++) {
                                item = (AListItem) items.elementAt(i);
                                if (!item.isPaint(x, y)) {
                                    lastIndex = i;
                                    break;
                                } else {
                                    y += item.getHeight();
                                }
                            }
                        } else {
                            y = getHeight() - getFooterHeight() - getStyle().getBodyStyle().getPadding().getBottom();
                            for (i = lastIndex; i >= firstIndex; i--) {
                                item = (AListItem) items.elementAt(i);
                                y -= item.getHeight();
                            }
                            if (y > getItemY()) {
                                for (i = firstIndex - 1; i >= 0; i--) {
                                    item = (AListItem) items.elementAt(i);
                                    y -= item.getHeight();
                                    if (!item.isPaint(x, y)) {
                                        firstIndex = i;

                                        break;
                                    }
                                }
                                if (firstIndex == 0 && y > getItemY()) {
                                    y = getItemY();
                                    for (i = 0; i < itemsSize; i++) {
                                        item = (AListItem) items.elementAt(i);
                                        y += item.getHeight();
                                        if (!item.isPaint(x, y)) {
                                            lastIndex = i;
                                            break;
                                        }
                                    }
                                }
                                itemY = getItemY();
                            } else {
                                itemY = y;
                            }
                        }
                    }
                }
                break;
        }
    }

    public void keyPressed(int key) {
        ICommandListener commandListener = getCommandListener();

        if (key == getLeftSoftKey()) {
            if (commandListener != null && getSelectCommand() != null) {
                commandListener.commandAction(getSelectCommand());
            }

        } else if (key == getRightSoftKey()) {
            if (commandListener != null && getCancelCommand() != null) {
                commandListener.commandAction(getCancelCommand());
            }
        } else {
            IKeyListener keyListener = getKeyListener();
            switch (key) {
                case KEY_NUM0:
                case KEY_NUM1:
                case KEY_NUM2:
                case KEY_NUM3:
                case KEY_NUM4:
                case KEY_NUM5:
                case KEY_NUM6:
                case KEY_NUM7:
                case KEY_NUM8:
                case KEY_NUM9:
                case KEY_STAR:
                case KEY_POUND:
                case FIRE:
                    if (keyListener != null) {
                        keyListener.keyAction(key);
                    }
                    break;
                default:
                    int gameAction = getGameAction(key);
                    if (gameAction == UP || gameAction == LEFT) {
                        oldIndex = newIndex;
                        newIndex--;
                        if (newIndex < 0) {
                            newIndex += items.size();
                        }
                        AListItem item = items.elementAt(newIndex);
                        if (item instanceof StringItem) {
                            int i;
                            boolean isHas = false;
                            for (i = newIndex - 1; i >= 0; i--) {
                                item = items.elementAt(i);
                                if (!(item instanceof StringItem)) {
                                    newIndex = i;
                                    isHas = true;
                                    break;
                                }
                            }
                            if (!isHas) {
                                for (i = items.size() - 1; i > newIndex; i--) {
                                    item = items.elementAt(i);
                                    if (!(item instanceof StringItem)) {
                                        newIndex = i;
                                        break;
                                    }
                                }
                            }
                        }
                        moveAction = MOVE_UP;
                        if (isAutoRepaint()) {
                            repaint();
                        }

                    } else if (gameAction == DOWN || gameAction == RIGHT) {
                        oldIndex = newIndex;
                        newIndex++;
                        newIndex = newIndex % items.size();
                        AListItem item = items.elementAt(newIndex);
                        if (item instanceof StringItem) {
                            int i;
                            boolean isHas = false;
                            for (i = newIndex + 1; i < items.size(); i++) {
                                item = items.elementAt(i);
                                if (!(item instanceof StringItem)) {
                                    newIndex = i;
                                    isHas = true;
                                    break;
                                }
                            }
                            if (!isHas) {
                                for (i = 0; i < newIndex; i++) {
                                    item = items.elementAt(i);
                                    if (!(item instanceof StringItem)) {
                                        newIndex = i;
                                        break;
                                    }
                                }
                            }
                        }
                        moveAction = MOVE_DOWN;
                        if (isAutoRepaint()) {
                            repaint();
                        }

                    } else if (gameAction == FIRE) {
                        AListItem item = getSelectedItem();
                        if (item instanceof RadioItem) {
                            RadioItem radio = (RadioItem) item;
                            if (!radio.isChecked()) {
                                radio.setChecked(true);
                                for (int i = 0; i < items.size(); i++) {
                                    AListItem a = items.elementAt(i);
                                    if (a instanceof RadioItem && a != radio) {
                                        if (((RadioItem) a).getGroup().equals(radio.getGroup())) {
                                            ((RadioItem) a).setChecked(false);
                                        }
                                    }
                                }
                                if (isAutoRepaint()) {
                                    repaint();
                                }
                            }
                        } else if (item instanceof CheckItem) {
                            CheckItem check = (CheckItem) item;
                            check.setChecked(!check.isChecked());
                            if (isAutoRepaint()) {
                                repaint();
                            }
                        }

                    }
                    if (keyListener != null) {
                        keyListener.keyAction(gameAction);
                    }
                    break;
            }
        }
    }
}
